﻿using System;
using System.Collections.Generic;

using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DAL.Interface;
using DAL.Models;

namespace DAL.Dao
{
    public class BagDaoimpl : BaseDao, IBagDaoimpl
    {

        public int ExistNum {
            get {
                int num = 0;
                using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
                {
                    num = context.Bag.Count();
                }
                return num;
            } 
            private set { } 
        }
        
        public BagDaoimpl(bool use_clock=true):base(use_clock)
        {
            
           
        }

        public IList<Bag> GetList()
        {
            IList<Bag> res = null;
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                res= (from i in context.Bag orderby i.Id select i).ToList();
            }
            return res;
        }

        public IList<Bag>[] GetList(string name, string phone)
        {
            List<Bag> senderList = null;
            List<Bag> getterList = null;
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                getterList = (from i in context.Bag where i.GetterName.Equals(name) && i.GetterPhone.Equals(phone) orderby i.Id select i).ToList();
                senderList = (from i in context.Bag where i.SenderName.Equals(name) && i.SenderPhone.Equals(phone) orderby i.Id select i).ToList();
            }
            return new List<Bag>[] { senderList,getterList};
        }

        public (int[], IList<Bag>[]) GetList(string name, string phone, int sernderRows, int senderPage, int getterRows, int getterPage)
        {
            IList<Bag> senderList=null;
            IList<Bag> getterList=null;
            using (ExpressDBContext context  = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                 getterList = (from i in context.Bag where i.GetterName.Equals(name) && i.GetterPhone.Equals(phone) orderby i.Id select i).ToList();
                 senderList = (from i in context.Bag where i.SenderName.Equals(name) && i.SenderPhone.Equals(phone) orderby i.Id select i).ToList();
            }
            return (new int[] { GetTotalPages(senderList.Count, sernderRows), GetTotalPages(getterList.Count, getterRows) },
                new List<Bag>[] { senderList.Skip((senderPage - 1) * sernderRows).Take(sernderRows).ToList(), getterList.Skip((getterPage - 1) * getterRows).Take(getterRows).ToList() });
        }




        public (int ,IList<Bag>) GetSenderList(string name, string phone,int rows,int page)
        {

            IList<Bag> ans = null;
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                ans = (from i in context.Bag where i.SenderName.Equals(name) && i.SenderPhone.Equals(phone) orderby i.Id select i).ToList();
            }
            return (GetTotalPages(ans.Count, rows), ans .Skip((page - 1) * rows).Take(rows).ToList());
           
           
        }

        public (int,IList<Bag>) GetGetterList(string name, string phone, int rows, int page)
        {
            IList<Bag> ans = null;
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                ans = (from i in context.Bag where i.GetterName.Equals(name) && i.GetterPhone.Equals(phone) orderby i.Id select i).ToList();

            }
            return (GetTotalPages(ans.Count, rows), ans.Skip((page - 1) * rows).Take(rows).ToList());

        }

        public (int,IList<Bag>) GetList(int rows, int page)
        {
            IList<Bag> ans = null;
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                ans = (from i in context.Bag orderby i.Id select i).ToList();
            }
            return (GetTotalPages(ans.Count, rows), ans.Skip((page - 1) * rows).Take(rows).ToList());
        }

        public Bag? GetItemByID(string id)
        {
            Bag? res = null;
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                res = (from i in context.Bag
                       where i.BagId.Equals(id)
                       select i).ToList().FirstOrDefault();
            }
                return res;
        }
        public IList<Bag> GetBagInfo(int id)
        {
            IList < Bag > info = null;
            //使用Lambda表达式查询数据
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                info = (from i in context.Bag
                        where i.Id == id
                        select i).ToList();
            }
            //var info = dbContext.PersonInfo.Where(i => i.Name == "ZhangSan").ToList();

            ////使用Linq语句查询
            //var info1 = from i in dbContext.PersonInfo
            //            where i.ID == 1
            //            select i;

            //获取查询结果
            //foreach (var item in info)
            //{
            //    Console.WriteLine(" Lambda方式的查询结果：姓名：" + item.UserName + " 年龄：" + item.UpdateTime);
            //}


            return info;
        }


        public bool Add(Bag bag)
        {
            lock (clock_obj_add)
            {
                try
                {
                    using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
                    {
                        context.Bag.Add(bag);
                        context.SaveChanges();
                    }
                       
                }
                catch (Exception e )
                {
                    return false;
                }
                return true;
            }
        }
        public Bag Find(string id)
        {
            Bag? res = null;
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                res = (from i in context.Bag where i.BagId.Equals(id) select i).ToList().FirstOrDefault(); 
            }
            return res;
        }

        public Bag? Find(int id)
        {
            Bag? res = null;
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                res = context.Bag.Find(id);
            }
            return res;
        }


        public bool Delete(int id)
        {
            lock (clock_obj_delete)
            {
                using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
                {
                    Bag? bag = (from i in context.Bag
                                where i.BagId.Equals(id)
                                select i).ToList().FirstOrDefault();

                    if (bag == null) return false;
                    context.Bag.Remove(bag);
                    context.SaveChanges();
                }
                return true;
            }
          
        }

        public int GetGetterUserIDByBagID(string bagID)
        {


            int res = 0;
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                res = (from i in context.UserInfo
                       from j in context.Bag
                       where (i.UserName.Equals(j.GetterName)) && j.BagId.Equals(bagID)
                       select i
                     ).Select(o => o.Id).ToList().FirstOrDefault();
                 
            }
            return res;

            //var linq = from s in mo.Userss
            //           from m in mo.Mission
            //           where s.UId == m.UId
            //           select new more
            //           {
            //               Uname = s.Uname,
            //               MId = m.MId,
            //               Time = m.Time,
            //               Price = m.Price
            //           };
            //return linq;
        }
        public int GetSenderUserIDByBagID(string bagID)
        {
            UserInfo? res = null;
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                res = (from i in context.UserInfo
                      from j in context.Bag
                      where (i.UserName.Equals(j.SenderName)) && j.BagId.Equals(bagID)
                      select i
                    ).FirstOrDefault();
            }

            if (res == null) return -1;
            return res.Id;

            //var linq = from s in mo.Userss
            //           from m in mo.Mission
            //           where s.UId == m.UId
            //           select new more
            //           {
            //               Uname = s.Uname,
            //               MId = m.MId,
            //               Time = m.Time,
            //               Price = m.Price
            //           };
            //return linq;
        }

        public IList<Bag> GetList(string bagId, int page, int rows)
        {
            
            //return View(db.Bags.ToList());
            //JsonResult json = new JsonResult();
            //json.Data = db.Bags.ToList();
            //return json;
            IList<Bag> list = null ;
            //int total = 0;
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                if (!string.IsNullOrWhiteSpace(bagId))
                {
                    list = (from i in context.Bag
                            where i.BagId.Equals(bagId)
                            select i).ToList();
                    //total = DbEntity.expressDBEntities.Bag.Where(o => o.BagID == bagId).Count();
                    //list = DbEntity.expressDBEntities.Bag.Where(o => o.BagID == bagId).OrderBy(o => o.ID).Skip((page - 1) * rows).Take(rows).ToList();
                }
                else
                {
                    list = (from i in context.Bag
                            orderby i.Id
                            select i).Skip((page - 1) * rows).Take(rows).ToList();
                    //list = DbEntity.expressDBEntities.Bag.OrderBy(o => o.ID).Skip((page - 1) * rows).Take(rows).ToList();
                }
            }
               
            return list;
            //return new ContentResult
            //{
            //    Content = new JavaScriptSerializer { MaxJsonLength = Int32.MaxValue }.Serialize(list),
            //    ContentType = "application/json"
            //};
        }


        //protected override void Dispose(bool disposing)
        //{
        //    DbEntity.expressDBEntities.Dispose();
        //    //base.Dispose(disposing);
        //}
        public bool DeleteBagInfo(string id)
        {
            lock (clock_obj_delete)
            {
                using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
                {
                    Bag? bag = (from i in context.Bag
                                where i.BagId.Equals(id)
                                select i).ToList().FirstOrDefault();
                    if (bag == null) return false;
                    context.Bag.Remove(bag);
                    context.SaveChanges();
                }
                   
                return true;
            }
           
        }


        public bool UpdateBagInfo(string id,Bag newbag,string mode="all")
        {
            using (ExpressDBContext context = new ExpressDBContext(DbEntity.DBContextOptions))
            {
                lock (clock_obj_update)
                {
                    try
                    {
                        Bag? bag = (from i in context.Bag
                                    where i.BagId.Equals(id)
                                    select i).ToList().FirstOrDefault();
                        if (bag == null)
                        {
                            return false;
                        }
                        //DbEntityEntry<Bag> entry = DbEntity.expressDBEntities.Entry<Bag>(newbag);
                        //3.设置该对象为被修改过
                        //entry.State = EntityState.Unchanged;
                        //4.设置该对象的 uName属性为修改状态，同时 entry.State 被修改为 Modified 状态
                        if (mode.Equals("all"))
                        {
                            bag.GetterName = newbag.GetterName;
                            bag.GetterPhone = newbag.GetterPhone;
                            bag.GetterAddress = newbag.GetterAddress;
                            bag.SenderName = newbag.SenderName;

                            bag.SenderPhone = newbag.SenderPhone;
                            bag.SenderAddress = newbag.SenderAddress;

                            bag.UpdateTime = newbag.UpdateTime;
                            bag.SendInfo = newbag.SendInfo;
                            //bag.ArriveInfo = newbag.ArriveInfo;
                            bag.AddTime = newbag.AddTime;
                        }
                        else if (mode.Equals("delivery_begin"))
                        {
                            bag.ArriveInfo = "派送中";
                            bag.UpdateTime = newbag.UpdateTime;
                        }
                        else if (mode.Equals("delivery_finish"))
                        {
                            bag.UpdateTime = newbag.UpdateTime;
                            bag.ArriveDate = newbag.ArriveDate;
                            bag.ArriveInfo = "送达";
                        }


                        //entry.Property("SendDate").IsModified = true;
                        //entry.Property("GetterName").IsModified = true;
                        //entry.Property("GetterPhone").IsModified = true;
                        //entry.Property("GetterAddress").IsModified = true;
                        //entry.Property("SenderName").IsModified = true;
                        //entry.Property("SenderPhone").IsModified = true;
                        //entry.Property("SenderAddress").IsModified = true;
                        //entry.Property("SendInfo").IsModified = true;
                        //entry.Property("UpdateTime").IsModified = true;
                        //entry.Property("AddTime").IsModified = true;
                        //entry.Property("ArriveInfo").IsModified = true;
                        //entry.Property("ArriveDate").IsModified = true;

                        //entry.State = EntityState.Modified;
                        //5.关闭EF实体合法性检查（如果创建出来的要修改的数据有的字段没有赋值则关闭实体合法性检查，如果所有字段都赋值了则不用关闭EF实体合法性检查）

                        //DbEntity.expressDBEntities.Configuration.ValidateOnSaveEnabled = false;

                        //6.重新保存到数据库 -- ef 上下文会根据实体对象的状态，根据 entry.State =Modified 的值生成对应的 update sql 语句.

                        context.SaveChanges();

                        return true;
                    }
                    catch (Exception e)
                    {

                        throw e.InnerException;
                    }
                   
                }

            }

        }
    }
}
